package cn.gov.pbc.tims.entity;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.ResourceBundle;

import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;

import com.sun.mail.imap.IMAPStore;
import com.sun.mail.pop3.POP3Folder;

import cn.gov.pbc.tims.util.ExcelUtil;

/**
 * 
 * @author H
 * 
 * 
 * 
 */

public class Mail {

	private MimeMessage mimeMessage = null;

	private String saveAttachPath = ""; // 附件下载后的存放目录
	private StringBuffer bodyText = new StringBuffer(); // 存放邮件内容的StringBuffer对象
	private String dateFormat = "yy-MM-dd HH:mm"; // 默认的日前显示格式
	private String messageId;
	private String subject;
	private List attachments;
	private String sentDate;
	private String from;
	
	
	/**
	 * 
	 * 构造函数,初始化一个MimeMessage对象
	 * 
	 */

	public Mail() {

	}
	public Mail(MimeMessage mimeMessage)throws Exception 
	{
		this.mimeMessage = mimeMessage;
		 
	}
	public Mail(MimeMessage mimeMessage,String uid) throws Exception {

		//this.mimeMessage = mimeMessage;
	    subject = mimeMessage.getSubject();
		// subject = MimeUtility.decodeText(mimeMessage.getSubject());
		// System.out.println("转换后的subject: " + mimeMessage.getSubject());
       if (subject == null) {
		 subject = "";
       }
        messageId = uid;
       
		InternetAddress address[] = (InternetAddress[]) mimeMessage.getFrom();
		String fromAdd = address[0].getAddress();
		if (fromAdd == null)  
			fromAdd = "";
		String personal = address[0].getPersonal();
		if (personal == null)  
			personal = "";
		String fromAddr = null;
		if (personal != null || fromAdd != null) 
			from = personal + "<" + fromAdd + ">";
		Date sentDate = mimeMessage.getSentDate();
		SimpleDateFormat format = new SimpleDateFormat(dateFormat);
		if(null!=sentDate)
			setSentDate(format.format(sentDate));
		
 		getMailContent((Part) mimeMessage);
 		attachments=getAttachments((Part) mimeMessage);
		//setReplySign(getReplySign());

		//System.out.println("创建一个ReceiveEmail对象....");

	}
	public Mail(MimeMessage mimeMessage,boolean fullInit)
	{
		
	}

	public void setMimeMessage(MimeMessage mimeMessage) {

		this.mimeMessage = mimeMessage;
	}

	/**
	 * 
	 * * 获得发件人的地址和姓名
	 * 
	 */

	public String getFrom() throws Exception {

		return from;

	}

	/**
	 * 
	 * * 获得邮件的收件人，抄送，和密送的地址和姓名，根据所传递的参数的不同
	 * 
	 * * "to"----收件人 "cc"---抄送人地址 "bcc"---密送人地址
	 * 
	 */

	public String getMailAddress(String type) throws Exception {

		String mailAddr = "";

		String addType = type.toUpperCase();

		InternetAddress[] address = null;

		if (addType.equals("TO") || addType.equals("CC")

				|| addType.equals("BCC")) {

			if (addType.equals("TO")) {

				address = (InternetAddress[]) mimeMessage

						.getRecipients(Message.RecipientType.TO);

			} else if (addType.equals("CC")) {

				address = (InternetAddress[]) mimeMessage

						.getRecipients(Message.RecipientType.CC);

			} else {

				address = (InternetAddress[]) mimeMessage

						.getRecipients(Message.RecipientType.BCC);

			}

			if (address != null) {

				for (int i = 0; i < address.length; i++) {

					String emailAddr = address[i].getAddress();

					if (emailAddr == null) {

						emailAddr = "";

					} else {

						//System.out.println("转换之前的emailAddr: " + emailAddr);

						emailAddr = MimeUtility.decodeText(emailAddr);

						//System.out.println("转换之后的emailAddr: " + emailAddr);

					}

					String personal = address[i].getPersonal();

					if (personal == null) {

						personal = "";

					} else {

						//System.out.println("转换之前的personal: " + personal);

						personal = MimeUtility.decodeText(personal);

						//System.out.println("转换之后的personal: " + personal);

					}

					String compositeto = personal + "<" + emailAddr + ">";

					//System.out.println("完整的邮件地址：" + compositeto);

					mailAddr += "," + compositeto;

				}

				mailAddr = mailAddr.substring(1);

			}

		} else {

			throw new Exception("错误的电子邮件类型!");

		}

		return mailAddr;

	}

	/**
	 * 
	 * * 获得邮件主题
	 * 
	 */

	public String getSubject()  {
 
       return this.subject;

	}

	/**
	 * 
	 * * 获得邮件发送日期
	 * 
	 */

	public String getSentDate() throws Exception {

		return sentDate;
	}

	/**
	 * 
	 * * 获得邮件正文内容
	 * @throws MessagingException 
	 * @throws IOException 
	 * 
	 */

	public String getBodyText() throws IOException, MessagingException {

		return  bodyText.toString();

	}

	/**
	 * 
	 * * 解析邮件，把得到的邮件内容保存到一个StringBuffer对象中，解析邮件
	 * 
	 * * 主要是根据MimeType类型的不同执行不同的操作，一步一步的解析
	 * 
	 */

	public void getMailContent(Part part) throws Exception {

		 //如果是文本类型的附件，通过getContent方法可以取到文本内容，但这不是我们需要的结果，所以在这里要做判断  
        boolean isContainTextAttach = part.getContentType().indexOf("name") > 0;   
        if (part.isMimeType("text/*") && !isContainTextAttach) {  
            bodyText.append(part.getContent().toString());  
        } else if (part.isMimeType("message/rfc822")) {   
        	getMailContent((Part)part.getContent());  
        } else if (part.isMimeType("multipart/*")) {  
            Multipart multipart = (Multipart) part.getContent();  
            int partCount = multipart.getCount();  
            for (int i = 0; i < partCount; i++) {  
                BodyPart bodyPart = multipart.getBodyPart(i);  
                getMailContent(bodyPart);  
            }  
        }  

	}

	/**
	 * 
	 * * 判断此邮件是否需要回执，如果需要回执返回"true",否则返回"false"
	 * 
	 */
	/*public boolean getReplySign() throws MessagingException {

		boolean replySign = false;

		String needReply[] = mimeMessage

				.getHeader("Disposition-Notification-To");

		if (needReply != null) {

			replySign = true;

		}

		if (replySign) {

			//System.out.println("该邮件需要回复");

		} else {

			//System.out.println("该邮件不需要回复");

		}

		return replySign;

	}*/

	/**
	 * 
	 * 获得此邮件的Message-ID
	 * 
	 */

	public String getMessageId() throws MessagingException {
		return messageId;
	}

	 

	/**
	 * 
	 * 判断此邮件是否包含附件
	 * 
	 */

	public boolean isContainAttach(Part part) throws Exception {

		boolean attachFlag = false;

		// String contentType = part.getContentType();

		if (part.isMimeType("multipart/*")) {

			Multipart mp = (Multipart) part.getContent();

			for (int i = 0; i < mp.getCount(); i++) {

				BodyPart mPart = mp.getBodyPart(i);

				String disposition = mPart.getDisposition();

				if ((disposition != null)

						&& ((disposition.toLowerCase().equals(Part.ATTACHMENT)) || (disposition

								.equals(Part.INLINE))))

					attachFlag = true;

				else if (mPart.isMimeType("multipart/*")) {

					attachFlag = isContainAttach((Part) mPart);

				} else {

					String conType = mPart.getContentType();

					if (conType.toLowerCase().indexOf("application") != -1)

						attachFlag = true;

					if (conType.toLowerCase().indexOf("name") != -1)

						attachFlag = true;

				}

			}

		} else if (part.isMimeType("message/rfc822")) {

			attachFlag = isContainAttach((Part) part.getContent());

		}

		return attachFlag;

	}
	public List getAttachments(Part part) throws Exception {
		List fileNameList=new ArrayList<String>();
		String fileName = "";

		if (part.isMimeType("multipart/*")) {

			Multipart mp = (Multipart) part.getContent();

			for (int i = 0; i < mp.getCount(); i++) {

				BodyPart mPart = mp.getBodyPart(i);

				String disposition = mPart.getDisposition();

				if ((disposition != null)

						&& ((disposition.toLowerCase().equals(Part.ATTACHMENT)) )) {

					fileName = mPart.getFileName();
					if ((fileName != null) && ((fileName.toLowerCase().indexOf("gb2312") != -1)||fileName.toLowerCase().indexOf("gbk") != -1)||(fileName.toLowerCase().indexOf("utf-8") != -1)) {
						fileName = MimeUtility.decodeText(fileName);
						//System.out.println("decode filename is" + fileName);
					}
					if (fileName != null)
					fileNameList.add("<a href='###' class='attachments'  >"+fileName+"</a>");

				} else if (mPart.isMimeType("multipart/*")) {

					getAttachments(mPart);

				} else {

					fileName = mPart.getFileName();
					if ((fileName != null) && (fileName.toLowerCase().indexOf("gb2312") != -1||fileName.toLowerCase().indexOf("gbk") != -1||fileName.toLowerCase().indexOf("utf-8")!= -1)) {
						fileName = MimeUtility.decodeText(fileName);
					}
					if (fileName != null)
					fileNameList.add("<a href='##' class='attachments'   >"+fileName+"</a>");
				}

			}
		} else if (part.isMimeType("message/rfc822")) {

			getAttachments((Part) part.getContent());

		}
		 return fileNameList;
	}
	public InputStream getAttachment(String fileNameTarget,Part part) throws Exception {
		String fileName = "";
		if (part.isMimeType("multipart/*")) {

			Multipart mp = (Multipart) part.getContent();

			for (int i = 0; i < mp.getCount(); i++) {

				BodyPart mPart = mp.getBodyPart(i);

				String disposition = mPart.getDisposition();

				if ((disposition != null)

						&& ((disposition.toLowerCase().equals(Part.ATTACHMENT)) )) {

				 fileName = mPart.getFileName();
					if ((fileName != null) && (fileName.toLowerCase().indexOf("gb2312") != -1||fileName.toLowerCase().indexOf("gbk") != -1||fileName.toLowerCase().indexOf("utf-8")!= -1)) {
					fileName = MimeUtility.decodeText(fileName);
				
					if(fileNameTarget.equals(fileName))
					{
						System.out.println("size11="+mPart.getSize());
						return  mPart.getInputStream();
					}
					}
				} else if (mPart.isMimeType("multipart/*")) {

					getAttachment(fileNameTarget,mPart);

				} else {

					fileName = mPart.getFileName();
					if ((fileName != null) && (fileName.toLowerCase().indexOf("gb2312") != -1||fileName.toLowerCase().indexOf("gbk") != -1||fileName.toLowerCase().indexOf("utf-8")!= -1)) {
						fileName = MimeUtility.decodeText(fileName);
						if(fileNameTarget.equals(fileName))
						{
							return  mPart.getInputStream();
						}
					}

				}

			}
		} else if (part.isMimeType("message/rfc822")) {

			getAttachment(fileNameTarget,(Part) part.getContent());

		}
		 return null;
	}
	public BodyPart getAttachmentPart(String fileNameTarget,Part part) throws Exception {
		String fileName = "";
		if (part.isMimeType("multipart/*")) {

			Multipart mp = (Multipart) part.getContent();

			for (int i = 0; i < mp.getCount(); i++) {

				BodyPart mPart = mp.getBodyPart(i);

				String disposition = mPart.getDisposition();

				if ((disposition != null)

						&& ((disposition.toLowerCase().equals(Part.ATTACHMENT)) )) {

				 fileName = mPart.getFileName();
					if ((fileName != null) && (fileName.toLowerCase().indexOf("gb2312") != -1||fileName.toLowerCase().indexOf("gbk") != -1||fileName.toLowerCase().indexOf("utf-8")!= -1)) {
					fileName = MimeUtility.decodeText(fileName);
				
					if(fileNameTarget.equals(fileName))
					{
						return  mPart;
					}
					}
				} else if (mPart.isMimeType("multipart/*")) {

					getAttachmentPart(fileNameTarget,mPart);

				} else {

					fileName = mPart.getFileName();
					if ((fileName != null) && (fileName.toLowerCase().indexOf("gb2312") != -1||fileName.toLowerCase().indexOf("gbk") != -1||fileName.toLowerCase().indexOf("utf-8")!= -1)) {
						fileName = MimeUtility.decodeText(fileName);
						if(fileNameTarget.equals(fileName))
						{
							return  mPart;
						}
					}

				}

			}
		} else if (part.isMimeType("message/rfc822")) {

			getAttachmentPart(fileNameTarget,(Part) part.getContent());

		}
		 return null;
	}
	/**
	 * 
	 * * 保存附件
	 * 
	 */

	public List<String> saveAttachMent(Part part) throws Exception {
		List fileNameList=new ArrayList<String>();

		String fileName = "";

		if (part.isMimeType("multipart/*")) {

			Multipart mp = (Multipart) part.getContent();

			for (int i = 0; i < mp.getCount(); i++) {

				BodyPart mPart = mp.getBodyPart(i);

				String disposition = mPart.getDisposition();

				if ((disposition != null)

						&& ((disposition.toLowerCase().equals(Part.ATTACHMENT)) || (disposition

								.equals(Part.INLINE)))) {

					fileName = mPart.getFileName();
					fileName = MimeUtility.decodeText(fileName);
					//System.out.println("decode filename is" + fileName);
					fileNameList.add(fileName);
					System.out.println("size21="+mPart.getSize());
					saveFile(fileName, mPart.getInputStream());

				} else if (mPart.isMimeType("multipart/*")) {

					saveAttachMent(mPart);

				} else {

					fileName = mPart.getFileName();
					if ((fileName != null) && (fileName.toLowerCase().indexOf("gb2312") != -1|| fileName.toLowerCase().indexOf("gbk") != -1||fileName.toLowerCase().indexOf("utf-8")!= -1)) {

						fileName = MimeUtility.decodeText(fileName);
						fileNameList.add(fileName);
						saveFile(fileName, mPart.getInputStream());

					}

				}

			}
		} else if (part.isMimeType("message/rfc822")) {

			saveAttachMent((Part) part.getContent());

		}
		return fileNameList;
	}

	/**
	 * 
	 * 设置附件存放路径
	 * 
	 */

	public void setAttachPath(String attachPath) {

		this.saveAttachPath = attachPath;

	}

	/**
	 * 
	 * * 设置日期显示格式
	 * 
	 */

	public void setDateFormat(String format) throws Exception {

		this.dateFormat = format;

	}

	/**
	 * 
	 * * 获得附件存放路径
	 * 
	 */

	public String getAttachPath() {

		return saveAttachPath;

	}

	/**
	 * 
	 * * 真正的保存附件到指定目录里
	 * 
	 */

	private void saveFile(String fileName, InputStream in) throws Exception {

		String osName = System.getProperty("os.name");

		String storeDir = getAttachPath();

		String separator = "";

		if (osName == null) {

			osName = "";

		}

		if (osName.toLowerCase().indexOf("win") != -1) {

			separator = "\\";

			if (storeDir == null || storeDir.equals(""))

				storeDir = "c:\\tmp";

		} else {

			separator = "/";

			storeDir = "/tmp";

		}

		File storeFile = new File(storeDir + separator + fileName);

		//System.out.println("附件的保存地址:　" + storeFile.toString());

		// for(int i=0;storefile.exists();i++){

		// storefile = new File(storedir+separator+fileName+i);

		// }

		BufferedOutputStream bos = null;

		BufferedInputStream bis = null;

		try {

			bos = new BufferedOutputStream(new FileOutputStream(storeFile));

			bis = new BufferedInputStream(in);

			int c;

			while ((c = bis.read()) != -1) {

				bos.write(c);

				bos.flush();

			}

		} catch (Exception exception) {

			exception.printStackTrace();

			throw new Exception("文件保存失败!");

		} finally {

			bos.close();

			bis.close();

		}

	}

	/**
	 * 
	 * ReceiveEmail类测试
	 * 
	 */

	public static void main(String args[]) throws Exception {

		/*String host = "ywmail.pbc.gov";

		String username = "kej.ta@sd.pbc.gov";

		String password = "sdtan0538";

		Properties props = new Properties();

		Session session = Session.getDefaultInstance(props, null);
		Store store = session.getStore("pop3");

		store.connect(host, username, password);
		*/
		
		/*Properties props = System.getProperties();  
        props.put("ywmail.pbc.gov", "ywmail.pbc.gov");  //这个是设置的session的默认服务器
        props.put("mail.smtp.auth", "true");  //这个设置认证
        Session session = Session.getDefaultInstance(props, null);  
        URLName urln = new URLName("pop3", "ywmail.pbc.gov", 110, null,  
                "kej.ta@sd.pbc.gov", "sdtan0538");  
        Store store = session.getStore(urln);  
        store.connect();  */      
        
		ResourceBundle resource=ResourceBundle.getBundle("config");
      
        Properties prop = System.getProperties();  
        //String user = "kej.ta@sd.pbc.gov";// 邮箱的用户名      
        //String password = "sdtan0538"; // 邮箱的密码      
        
        String user = resource.getString("username");// 邮箱的用户名      
        String password = resource.getString("password"); // 邮箱的密码      
        String beginDate=resource.getString("beginDate"); 
        
        prop.put("mail.store.protocol", "imap"); 

        //prop.put("mail.imap.host", "ywmail.pbc.gov"); 
        prop.put("mail.imap.host", resource.getString("mail.imap.host"));
        
        Session session = Session.getInstance(prop);      
              
        int total = 0;      
        IMAPStore store = (IMAPStore) session.getStore("imap"); // 使用imap会话机制，连接服务器      
        store.connect(user, password); 
        
        
		Folder folder = store.getFolder("INBOX");
		folder.open(Folder.READ_ONLY);
		Message[] messages = folder.getMessages();
		
		//按照日期排序
		//SortTerm[] term =new SortTerm[1];
		//term[0]=SortTerm.DATE;
	    //IMAPFolder imapFolder=(IMAPFolder)folder;
	    //imapFolder.open(Folder.READ_ONLY);
	    //Message[] messages=imapFolder.getSortedMessages(term);
	        
		
		//System.out.println("邮件数量:　" + messages.length);
		//System.out.println("未读邮件数量:　" + folder.getUnreadMessageCount());
		//System.out.println("新邮件数量:　" + folder.getNewMessageCount());
		Mail re = null;

		for (int i = 0; i < messages.length; i++) {
			
			MimeMessage message=(MimeMessage) messages[i];
			re = new Mail(message,((POP3Folder)folder).getUID(message));
			
			re.setDateFormat("yyyy-MM-dd");
			//System.out.println("邮件 " + i + " 发送时间: " + re.getSentDate());
			SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
			//if(sdf.parse(beginDate).before(sdf.parse(re.getSentDate())))
				
			List list=new ArrayList<String>();
			list.add(re.getMessageId());
			
			//System.out.println("邮件 " + i + " 是否已读: " + re.isNew());
			//if(re.isNew())
			//	{
				//System.out.println("-------------------------------------------");
				//System.out.println("邮件　" + i + "　主题:　" + re.getSubject());
			    //System.out.println("邮件 " + i + " 发送时间: " + re.getSentDate());

			// System.out.println("邮件 " + i + " 是否需要回复: " + re.getReplySign());


			// System.out.println("邮件　" + i + "　是否包含附件:　"

			//		+ re.isContainAttach((Part) messages[i]));

			 //System.out.println("邮件 " + i + " 发送人地址: " + re.getFrom());

			 //System.out.println("邮件 " + i + " 收信人地址: " +
			 //re.getMailAddress("to"));

			// System.out.println("邮件 " + i + " 抄送: " +
			// re.getMailAddress("cc"));

			// System.out.println("邮件 " + i + " 暗抄: " +
			// re.getMailAddress("bcc"));
			//System.out.println("邮件　" + i + "　发送时间:　" + re.getSentDate());
			 list.add(re.getSentDate());
			 list.add(re.getSubject());
			 list.add(re.getFrom());
			 re.getMailContent((Part) messages[i]);
			 list.add(re.getBodyText());
			//System.out.println("邮件　" + i + "　正文内容:　\r\n" + re.getBodyText());

			re.setAttachPath("e:\\mail\\attchment");

			List<String> filenameList=re.saveAttachMent((Part) messages[i]);
			for(String filename : filenameList)
				{
				String[] strs={filename,"hyperlink","e:\\mail\\attchment\\"+filename};
				list.add(strs);
				}
			//}
          ExcelUtil.appendExcel("e:\\mail\\maillist.xls", list);
		}
		store.close();
		
	}

	public void setSaveAttachPath(String saveAttachPath) {
		this.saveAttachPath = saveAttachPath;
	}

	public void setBodyText(StringBuffer bodyText) {
		this.bodyText = bodyText;
	}

	 
	public void setSubject(String subject) {
		this.subject = subject;
	}

 

	public void setMessageId(String messageId) {
		this.messageId = messageId;
	}

 
	public void setSentDate(String sentDate) {
		this.sentDate = sentDate;
	}

	public void setFrom(String from) {
		this.from = from;
	}

	public List getAttachments() {
		return attachments;
	}

	public void setAttachments(List attachments) {
		this.attachments = attachments;
	}

	 

	 
	 

}
